package com.wiki.gds.user.provider.modular.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.wiki.gds.base.common.utils.StringUtil;
import com.wiki.gds.base.security.admin.utils.SecurityUtil;
import com.wiki.gds.user.facade.sys.model.Resource;
import com.wiki.gds.user.facade.sys.vo.vue.MenuVo;
import com.wiki.gds.user.facade.sys.vo.vue.MetaVo;
import com.wiki.gds.user.provider.modular.sys.mapper.ResourceDao;
import com.wiki.gds.user.provider.modular.sys.service.ResourceService;
import org.beetl.sql.core.Params;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.engine.PageQuery;
import org.beetl.sql.core.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private SQLManager sqlManager;

    @Autowired
    ResourceDao resourceDao;


    @Override
    public List<Map> findUserResourceByUid(Long uid) {
        String sql="select a.url,d.name from sys_resource a join sys_role_resource b on a.id=b.resource_id join sys_user_role c on b.role_id=c.role_id " +
                "join sys_role d on d.id=b.role_id " +
                "where c.user_id=#uid#";
        return sqlManager.execute(sql,Map.class, Params.ins().add("uid", uid).map());
    }

    @Override
    public List<MenuVo> getMenu(Long uid) {
        String sql="select DISTINCT a.* from sys_resource a join sys_role_resource b on a.id=b.resource_id join sys_user_role c on b.role_id=c.role_id " +
                "join sys_role d on d.id=b.role_id " +
                "where c.user_id=#uid# and a.status!=-1 and a.resource_type=0 order by a.pid,a.seq";
       List<Resource> resources= sqlManager.execute(sql,Resource.class, Params.ins().add("uid", uid).map());
        return treeList(resources,0l);
    }

    @Override
    public List<Map> getResourceTreeList(Map map) {
        List<Resource> list=this.getList(map);
        return resourceTree(list,0l);
    }

    public List<Map> resourceTree(List<Resource> resourceList,Long parentId){
        List<Map> list=  list=null;
        for(Resource resource:resourceList){
            if(resource.getPid().longValue()==parentId.longValue()){
                Map map=BeanUtil.beanToMap(resource);
//                 pidArray:data[i].pids.split(','),
                List<Long> pidArray=new ArrayList<>();
                for(String a:resource.getPids().split(",")){
                    if(!StrUtil.isEmpty(a)){
                        pidArray.add(Long.valueOf(a));
                    }
                }
                map.put("pidArray",pidArray);
                List<Map> children=this.resourceTree(resourceList,resource.getId());
                map.put("children",children);
                if(list==null){
                    list=new ArrayList<>();
                }
                list.add(map);
            }
        }
        return list;
    }


    public List<MenuVo> treeList(List<Resource> resourceList,Long parentId){
        List<MenuVo> list=null;
        for(Resource resource:resourceList){
            if(resource.getPid().longValue()==parentId.longValue()){
                MenuVo menuVo=new MenuVo();
                menuVo.setName(resource.getComponentName());
                menuVo.setComponentName(resource.getName());
                if(StringUtil.isEmpty(resource.getUrl())){
                    menuVo.setPath("");
                }
                else {
                    menuVo.setPath(resource.getUrl());
                }

                menuVo.setComponent(resource.getComponentPath());
                menuVo.setStatus(resource.getStatus());
                MetaVo metaVo =new MetaVo();
                metaVo.setIcon(resource.getIcon());
                metaVo.setTitle(resource.getName());
                menuVo.setMeta(metaVo);
                List<MenuVo> child=treeList(resourceList,resource.getId());
                menuVo.setChildren(child);
                if(list==null){
                    list=new ArrayList<>();
                }
                list.add(menuVo);
            }
        }
        return list;
    }

    @Override
    public Long insert(Resource resource) {
        resource.setCreateTime(new Date());
        resource.setCreateBy(SecurityUtil.getSecurityUser().getId());
       Long rs= resourceDao.insertReturnKey(resource).getLong();
        return rs>0?rs:null;
    }

    @Override
    public Boolean update(Resource resource) {
        resource.setUpdateTime(new Date());
        resource.setUpdateBy(SecurityUtil.getSecurityUser().getId());
        Integer rs=  resourceDao.updateTemplateById(resource);
        return rs>0?true:false;
    }

    @Override
    public Boolean del(Resource resource) {


        return null;
    }

    @Override
    public Resource getById(Long id) {
        return null;
    }

    @Override
    public List<Resource> getList(Map map) {
      Query<Resource> query= sqlManager.query(Resource.class);
      query.andNotEq("status","-1");
        map.forEach((key, value) -> {
            query.andEq((String)key,value);
        });

      return query.select();
    }

    @Override
    public List<Map> findDeptResource() {
        Long deptId=SecurityUtil.getSecurityUser().getDeptId();
        String sql="select DISTINCT a.id,a.pid,a.name from sys_resource a left join sys_role_resource b on a.id=b.resource_id" +
                " where b.role_id in (SELECT  DISTINCT e.role_id  from sys_user c left join sys_dept d on c.dept_id=d.id" +
                " join sys_user_role e on c.id=e.user_id" +
                " where c.dept_id=#deptId# or d.pids like CONCAT('%[',#deptId#,']%'))" +
                " and a.`status`!=-1";
        Map map=new HashMap();
        map.put("deptId",deptId);
        if(deptId==0){
            sql+=" or (a.`status`!=-1)";
        }
        return sqlManager.execute(sql,Map.class,map);
    }

    @Override
    public void getPageList(PageQuery query) {
             resourceDao.templatePage(query);
    }

    @Override
    public Long getCount(Resource resource) {
        return null;
    }

    @Override
    public Resource getBySelf(Resource resource) {
        return null;
    }

    @Override
    public Long saveOrUpdate(Resource resource) {

        if(StringUtil.isEmpty(resource.getId())) {
            this.insert(resource);
            return null;
        }else {
            this.update(resource);
            return null;
        }
    }
}
